package org.darkbits.cyklon.engine;

import org.darkbits.cyklon.machine.Input;
import org.darkbits.cyklon.machine.Output;
import org.darkbits.cyklon.machine.Processable;

public class Connector implements Processable {
	Input inputPort;
	Output outputPort;
	ConnectedMachine inputMachine, outputMachine;

	public Connector(Input inputPort, Output outputPort, ConnectedMachine inputMachine, ConnectedMachine outputMachine) {
		this.inputPort = inputPort;
		this.outputPort = outputPort;
		this.inputMachine = inputMachine;
		this.outputMachine = outputMachine;
		inputMachine.addInputConnector(this);
		inputMachine.addOutputConnector(this);
	}
	
	public void breakConnection() {
		inputMachine.removeInputConnector(this);
		outputMachine.removeOutputConnector(this);
	}

	public void process(int samples) {
		Object data = null;
		
		// TODO: Proper error handling
		
		try {
			if (outputMachine.isEnabled()) {
				data = outputPort.read();
			}
		} catch (Exception e) {
			outputMachine.setEnabled(false);
			System.out.println("Error when transferring from output " + outputPort.getName() + " on machine " + outputPort.getOwner().getClass().getName());
		}
		
		try {
			if (inputMachine.isEnabled()) {
				inputPort.write(data);
			}
		} catch (Exception e) {
			inputMachine.setEnabled(false);
			System.out.println("Error when transferring to input " + inputPort.getName() + " on machine " + outputPort.getOwner().getClass().getName());
		}
	}
	
	public Input getInput() {
		return inputPort;
	}

	public void setInput(Input input) {
		this.inputPort = input;
	}

	public Output getOutput() {
		return outputPort;
	}

	public void setOutput(Output output) {
		this.outputPort = output;
	}

	public ConnectedMachine getInputMachine() {
		return inputMachine;
	}

	public void setInputMachine(ConnectedMachine inputMachine) {
		this.inputMachine = inputMachine;
	}

	public ConnectedMachine getOutputMachine() {
		return outputMachine;
	}

	public void setOutputMachine(ConnectedMachine outputMachine) {
		this.outputMachine = outputMachine;
	}
}
